package com.cooper.scraper.show;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.cooper.android.comm.LRULinkedHashMap;
import com.cooper.scraper.RunnerSubscribe;
import com.cooper.scraper.DownloadPublishRunner;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

public class OnlineFanartViewStrategy<T extends OnlineFanartResource> extends
		FanartViewStrategy<T> implements RunnerSubscribe {

	private final static int HOLDER_WAITING_SIZE = 40;

	private static final String DOWNLOAD_KEY_PREFIX = "ONLINE_FANART_DOWNLOAD_";

	private Context context;

	private DownloadPublishRunner downloader;

	private FanartImgStrategy fanartImgStrategy;

	// Gallery have a bug convertView is always null
	private Map<FanartViewHolder<T>, T> waitingHolders = new LRULinkedHashMap<FanartViewHolder<T>, T>(
			HOLDER_WAITING_SIZE);

	public OnlineFanartViewStrategy(Context context, DownloadPublishRunner downloader) {
		super();
		this.downloader = downloader;
		this.context = context;
	}

	@Override
	public Bitmap getMediaFanart(T resource, float fanartWidth,
			float fanartHeight) {
		Bitmap result = cache.get(resource.getId());
		if (result == null) {
			downloader.downloadBitmap(resource.getFanartUrl(),resource.getReferer(),
					DOWNLOAD_KEY_PREFIX + resource.getFanartUrl(), fanartWidth,
					fanartHeight);
		}
		return result;
	}

	@Override
	public void onReturnView(FanartViewHolder<T> holder, int type) {
		if (type == WAIT_VIEW_TYPE) {
			waitingHolders.put(holder, holder.getResource());
		} else if (type == FANART_VIEW_TYPE) {
			List<FanartViewHolder<T>> outHolders = new ArrayList<FanartViewHolder<T>>();
			for (FanartViewHolder<T> keyHolder : waitingHolders.keySet()) {
				if (holder.getResource().equals(keyHolder.getResource())) {
					outHolders.add(keyHolder);
				}
			}
			for (FanartViewHolder<T> outHolder : outHolders) {
				waitingHolders.remove(outHolder);
			}
		}
	}

	@Override
	public void onConverView(FanartViewHolder<T> holder) {
		if (waitingHolders.keySet().contains(holder)) {
			T media = holder.getResource();
			if (media != null) {
				downloader.cancel(DOWNLOAD_KEY_PREFIX + media.getFanartUrl());
			}
			holder.clean();
			waitingHolders.remove(holder);
		}
	}

	@Override
	public void init(FanartImgStrategy fanartImgStrategy, int showCount) {

		this.fanartImgStrategy = fanartImgStrategy;
		if (cache != null) {
			cache.clear();
		}
		cache = new LRULinkedHashMap<String, Bitmap>(showCount * 4);
		Log.d("OnlineFanartViewStrategy", "cache size:" + showCount + "* 4");
		cache.setRemoveEldestEntryListener(this);
		downloader.cancel(this);
		downloader.subscribe(this);

	}

	@Override
	public void destroy() {
		super.destroy();
		waitingHolders.clear();
		downloader.cancelSubscribe(this, false);
	}

	@Override
	public void reset() {
		downloader.cancel(this);
		super.reset();
	}


	private List<FanartViewHolder<T>> getKeyHolders(String key) {
		List<FanartViewHolder<T>> result = new ArrayList<FanartViewHolder<T>>();
		for (FanartViewHolder<T> holder : waitingHolders.keySet()) {
			if (key.endsWith(holder.getResource().getFanartUrl())) {
				result.add(holder);
			}
		}
		return result;
	}

	@Override
	public void onDownloadComplete(String key, Object data) {
		boolean setImg = false;
		List<FanartViewHolder<T>> keyHolders = getKeyHolders(key);

		Bitmap result = fanartImgStrategy.handleFanartImg(context,
				(Bitmap) data);
		for (FanartViewHolder<T> holder : keyHolders) {
			if (!setImg)
				cache.put(holder.getResource().getId(), result);
			holder.setFanart(result);
			setImg = true;
			waitingHolders.remove(holder);
		}

		if (!setImg && result != null && !result.isRecycled()) {
			result.recycle();
			Log.d("OnlineFanartViewStrategy", "not find view:" + key);
		}
	}

	@Override
	public void onDownloadFail(String key, int errorCode) {
		List<FanartViewHolder<T>> keyHolders = getKeyHolders(key);
		for (FanartViewHolder<T> holder : keyHolders) {
			// set fail img
			// Bitmap result = fanartImgStrategy.handleFanartImg(context,
			// (Bitmap) data);
			// holder.setFanart(result);

			waitingHolders.remove(holder);
		}

	}

	@Override
	public void onDownloadCancel(String key) {
	}

	@Override
	public boolean subscribed(String key) {
		return key.startsWith(DOWNLOAD_KEY_PREFIX);
	}

}
